package com.admin.education.services.Implements;

import com.admin.education.common.exceptions.BadRequestException;
import com.admin.education.common.exceptions.ResourceNotFoundException;
import com.admin.education.dataTransferObject.PageRequest;
import com.admin.education.dataTransferObject.PageResponse;
import com.admin.education.dataTransferObject.ServicesExcuteResult;
import com.admin.education.dataTransferObject.categorys.CategoryTemplateTransfer;
import com.admin.education.dataTransferObject.userRecord.UserRecordTransfer;
import com.admin.education.dataTransferObject.votes.Mapper.VotesMapper;
import com.admin.education.dataTransferObject.votes.Request.CreateVotesRequest;
import com.admin.education.dataTransferObject.votes.Request.UpdateVotesRequest;
import com.admin.education.dataTransferObject.votes.Request.VotesRequest;
import com.admin.education.dataTransferObject.votes.VotesTransfer;
import com.admin.education.models.*;
import com.admin.education.repositories.CategorysRepository;
import com.admin.education.repositories.VotesDetailRepository;
import com.admin.education.repositories.VotesRepository;
import com.admin.education.repositories.VotesResultRepository;
import com.admin.education.services.Interfaces.IVotesService;
import com.querydsl.jpa.impl.JPAQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;

@Service
@Transactional
@Slf4j
public class VotesService implements IVotesService {
    @Autowired
    private CategorysRepository categorysRepository;
    @Autowired
    private VotesMapper votesMapper;
    @Autowired
    private VotesRepository votesRepository;
    @Autowired
    private VotesResultRepository votesResultRepository;
    @Autowired
    private VotesDetailRepository votesDetailRepository;
    private QVotes qVotes;
    private QCategorys qCategorys;
    private QVotesDetail qVotesDetail;
    private QVotesResult qVotesResult;
    public VotesService(){
        qCategorys=QCategorys.categorys;
        qVotes =QVotes.votes;
        qVotesDetail = QVotesDetail.votesDetail;
        qVotesResult =QVotesResult.votesResult;
    }

    @Override
    public ServicesExcuteResult<List<VotesTransfer>> queryVotes(long categorys) throws ResourceNotFoundException {
        ServicesExcuteResult<List<VotesTransfer>> servicesExcuteResult = new ServicesExcuteResult<>();

        Categorys category= this.categorysRepository.selectFrom(qCategorys).where(qCategorys.valid.eq(true),qCategorys.id.eq(categorys)).fetchOne();
        if(null!=category) {
            servicesExcuteResult.setData(votesMapper.mapFrom(category.getVotes()));
            servicesExcuteResult.setSuccess(true);
        }
        else{
            throw new ResourceNotFoundException("分类不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<VotesTransfer> queryVotesById(long votesId) throws ResourceNotFoundException {
        ServicesExcuteResult<VotesTransfer> servicesExcuteResult = new ServicesExcuteResult<>();

        Votes votes= this.votesRepository.selectFrom(qVotes).where(qVotes.id.eq(votesId)).fetchOne();
        if(null!=votes) {
            VotesTransfer votesTransfer = new VotesTransfer();
            votesTransfer.setInclude(true);

            servicesExcuteResult.setData(votesMapper.mapFrom(votes,votesTransfer));
            servicesExcuteResult.setSuccess(true);
        }
        else{
            throw new ResourceNotFoundException("投票不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult ballots(long votesId, String openId, List<VotesRequest> votesRequests) throws ResourceNotFoundException, BadRequestException {
        ServicesExcuteResult servicesExcuteResult =new ServicesExcuteResult();

        Votes votes= this.votesRepository.selectFrom(qVotes).where(qVotes.id.eq(votesId)).fetchOne();
        if(null!=votes) {
            List<VotesResult> votesResults  = votes.ballots(openId,votesRequests);
            if(null!=votesRequests){
                this.votesResultRepository.persist(votesResults);
            }
            servicesExcuteResult.setSuccess(true);
        }
        else{
            throw new ResourceNotFoundException("投票不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult creaateVotes(@Valid CreateVotesRequest createVotesRequest) throws BadRequestException {
        ServicesExcuteResult servicesExcuteResult =new ServicesExcuteResult();

        Votes votes =this.votesMapper.mapFrom(createVotesRequest);
        votes.setCreateTime(new Date());

        this.votesRepository.persist(votes);
        this.votesDetailRepository.persist(votes.getVotesDetails());

        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult deleteVotes(long votesId) throws ResourceNotFoundException {
        ServicesExcuteResult servicesExcuteResult =new ServicesExcuteResult();

        Votes votes= this.votesRepository.selectFrom(qVotes).where(qVotes.id.eq(votesId)).fetchOne();
        if(null!=votes) {
            this.votesResultRepository.delete(qVotesResult).where(qVotesResult.votes.id.eq(votesId)).execute();
            this.votesDetailRepository.delete(qVotesDetail).where(qVotesDetail.votes.id.eq(votesId)).execute();

            this.votesRepository.remove(votes);
            servicesExcuteResult.setSuccess(true);
        }
        else{
            throw new ResourceNotFoundException("投票不存在");
        }
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult<PageResponse<VotesTransfer>> queryVotes(@Valid PageRequest pageRequest) {
        ServicesExcuteResult<PageResponse<VotesTransfer>> servicesExcuteResult=new ServicesExcuteResult<>();

        JPAQuery<Votes> votesJPAQuery = this.votesRepository.selectFrom(qVotes);


        long totalCount = votesJPAQuery.fetchCount();

        votesJPAQuery = votesJPAQuery.orderBy(qVotes.createTime.desc()).offset((pageRequest.getPageIndex()-1)*pageRequest.getPageSize()).limit(pageRequest.getPageSize());

        List<Votes> votes= votesJPAQuery.fetch();

        List<VotesTransfer> votesTransfers = this.votesMapper.mapFrom(votes);

        PageResponse<VotesTransfer> votesTransferPageResponse = new PageResponse<>(pageRequest.getPageSize(),pageRequest.getPageIndex(),(int)totalCount,votesTransfers);

        servicesExcuteResult.setData(votesTransferPageResponse);
        servicesExcuteResult.setSuccess(true);
        return servicesExcuteResult;
    }

    @Override
    public ServicesExcuteResult updateVotes(long votesId, @Valid UpdateVotesRequest updateVotesRequest) throws ResourceNotFoundException, BadRequestException {
        ServicesExcuteResult servicesExcuteResult =new ServicesExcuteResult();

        Votes votes= this.votesRepository.selectFrom(qVotes).where(qVotes.id.eq(votesId)).fetchOne();
        if(null!=votes) {

            for (VotesDetail votesDetail : votes.getVotesDetails()) {
                this.votesDetailRepository.remove(votesDetail);
            }
            votes = this.votesMapper.mapFrom(updateVotesRequest,votes);

            this.votesDetailRepository.persist(votes.getVotesDetails());
            this.votesRepository.merge(votes);
            servicesExcuteResult.setSuccess(true);
        }
        else{
            throw new ResourceNotFoundException("投票不存在");
        }
        return servicesExcuteResult;
    }
}
